home *** CD-ROM | disk | FTP | other *** search
/ Stone Design / Stone Design.iso / Stone_Friends / Wave / WavesWorld / Source / IBPalettes / WWTCLKit / WWSimpleImageView.m < prev    next >
Encoding:
Text File  |  1995-03-22  |  14.2 KB  |  544 lines

  1. #import "WWSimpleImageView.h"
  2. #import "aspectRatios.h"
  3.  
  4. @implementation WWSimpleImageView
  5.  
  6.  
  7. #define WW_BOTTOMALIGNED  0
  8. #define WW_TOPALIGNED     1
  9.  
  10.  
  11. + initialize { return [WWSimpleImageView setVersion:6], self; }
  12.  
  13. - initFrame:(const NXRect *)r 
  14. {
  15.    [super initFrame:r];
  16.    backgroundColor = NXConvertRGBToColor(0.96, 1.0, 0.6);
  17.    borderType = 0;
  18.    alpha = 1.0;
  19.    image = nil;
  20.    aspectRatioType = WW_ASPECT_DONT_CARE;
  21.    aspectRatio = 1.0;
  22.    scaleToFit = NO;
  23.    imageUnder = NO;
  24.    horizontalLayoutType = NX_LEFTALIGNED;
  25.    verticalLayoutType = WW_BOTTOMALIGNED;
  26.  
  27.    return self;
  28. }
  29.  
  30. - awake
  31. {
  32.    [super awake];
  33.    return self;
  34. }
  35.  
  36.  
  37. - free
  38. {
  39.   if (controlPanel)
  40.   {  [controlPanel setFreeWhenClosed:NO];
  41.      [controlPanel close];
  42.      [controlPanel free];
  43.      controlPanel = nil;
  44.   }
  45.   return [super free];
  46. }
  47. #define EPSILON 10
  48.  
  49. - sizeTo:(NXCoord)width :(NXCoord)height
  50. {
  51.   // don't want to make it too small...
  52.   if (width < EPSILON) return nil;
  53.   if (height < EPSILON) return nil;
  54.  
  55.  
  56.   // let's say it comes in at 100, 100 and you're supposed to be constrained to 4:3
  57.   // you don't want it to get bigger than 100, 100, so... you frob the width, not the height
  58.   switch (aspectRatioType)
  59.   {  case WW_ASPECT_DONT_CARE:
  60.             aspectRatio = width/height;
  61.             break;
  62.      case WW_ASPECT_NTSC:  // 1.33:1
  63.             height = width/1.33;
  64.             aspectRatio = 1.33;
  65.             break;
  66.      case WW_ASPECT_AMERICAN_WIDESCREEN:  // 1.85:1
  67.             //width = height * 1.85;
  68.             height = width/1.85;
  69.             aspectRatio = 1.85;
  70.             break;
  71.      case WW_ASPECT_EUROPEAN_WIDESCREEN:  // 1.66:1
  72.             //width = height * 1.66;
  73.             height = width/1.66;
  74.             aspectRatio = 1.66;
  75.             break;
  76.      case WW_ASPECT_VISTA_VISION:  // 2.21:1
  77.             //width = height * 1.21;
  78.             height = width/2.21;
  79.             aspectRatio = 2.21;
  80.             break;
  81.      case WW_ASPECT_SQUARE:  // 1:1
  82.             if (width < height)
  83.         {  height = width;
  84.         }
  85.         else
  86.         {  width = height;
  87.         }
  88.             aspectRatio = 1.0;
  89.             break;
  90.      case WW_ASPECT_CUSTOM:  //aspectX:aspectY
  91.             if (aspectRatio < 1.0)
  92.         {  width = height * aspectRatio;
  93.         }
  94.         else
  95.         {  height = width/aspectRatio;
  96.         }
  97.             break;
  98.      default:
  99.             NXLogError("unknown aspect ratio type: %d", aspectRatioType);
  100.             break;
  101.   }
  102.  
  103.   [super sizeTo:width :height];
  104.   [self display];
  105.  
  106.   return self;
  107. }
  108.  
  109. - drawSelf:(const NXRect *)theRect :(int)n 
  110. {
  111.   NXPoint  p = {0.0, 0.0};
  112.   NXSize   imageSize;
  113.  
  114.  
  115.   if (clearTheView)  
  116.   {  NXSetColor(backgroundColor);
  117.      PSsetalpha(0.0);
  118.      PScompositerect(theRect->origin.x, theRect->origin.y, 
  119.              theRect->size.width, theRect->size.height,
  120.              NX_SOVER);
  121.      return self;
  122.   }
  123.  
  124.   [image getSize:&imageSize];
  125.   switch (verticalLayoutType)
  126.   {  case WW_BOTTOMALIGNED:
  127.           p.y = 0.0;
  128.       break;
  129.      case WW_TOPALIGNED:
  130.           p.y = theRect->size.height - imageSize.height;
  131.        break;
  132.     default:
  133.           p.y = 0.0;
  134.       break;
  135.   }
  136.   switch (horizontalLayoutType)
  137.   {  case NX_LEFTALIGNED:
  138.           p.x = 0.0;
  139.       break;
  140.      case NX_RIGHTALIGNED:
  141.           p.x = theRect->size.width - imageSize.width;
  142.        break;
  143.      case NX_CENTERED:
  144.           if (theRect->size.width > imageSize.width)
  145.           {  p.x = (theRect->size.width - imageSize.width)/2.0;
  146.           }
  147.           else
  148.           {  p.x = 0.0;
  149.           }
  150.           if (theRect->size.height > imageSize.height)
  151.           {  p.y = (theRect->size.height - imageSize.height)/2.0;
  152.           }
  153.           else
  154.           {  p.y = 0.0;
  155.           }
  156.       break;
  157.     default:
  158.           p.x = 0.0;
  159.       break;
  160.   }
  161.  
  162.   if (imageUnder)
  163.   {  if (scaleToFit)
  164.      {  [[image bestRepresentation] drawIn:(const NXRect *)&bounds];
  165.      }
  166.      else
  167.      {  [image composite:NX_SOVER toPoint:&p];
  168.      }
  169.      NXSetColor(backgroundColor);
  170.      PSsetalpha(alpha);
  171.      PScompositerect(theRect->origin.x, theRect->origin.y, 
  172.              theRect->size.width, theRect->size.height,
  173.              NX_SOVER);
  174.   }
  175.   else
  176.   {  NXSetColor(backgroundColor);
  177.      PSsetalpha(alpha);
  178.      PScompositerect(theRect->origin.x, theRect->origin.y, 
  179.              theRect->size.width, theRect->size.height,
  180.              NX_SOVER);
  181.      if (scaleToFit)
  182.      {  [[image bestRepresentation] drawIn:(const NXRect *)&bounds];
  183.      }
  184.      else
  185.      {  [image composite:NX_SOVER toPoint:&p];
  186.      }
  187.   }  
  188.  
  189.   if (borderType)
  190.   {  NXRect  r = *theRect;
  191.  
  192.  
  193.      PSsetalpha(1.0);
  194.  
  195.      r.origin.x++; r.origin.y--;        
  196.      NXSetColor(NX_COLORBLACK); NXFrameRect(&r);
  197.  
  198.      r.origin.x--, r.origin.y++;        
  199.      NXSetColor(NX_COLORGRAY); NXFrameRect(&r);
  200.  
  201.      r.origin.x--; r.size.width++; r.size.height++; 
  202.      NXSetColor(NX_COLORWHITE); NXFrameRect(&r);
  203.   }
  204.  
  205.   return self;
  206. }
  207.  
  208. - setBorderType:(int)newBorderType { borderType = newBorderType; return self; }
  209. - (int)borderType { return borderType; }
  210.  
  211. //
  212. - sizeToImage:sender 
  213. {
  214.    NXSize s;
  215.  
  216.  
  217.     if (image)
  218.     {  [image getSize:&s];
  219.        [self sizeTo:s.width :s.height];
  220.     }
  221.     return self;
  222. }
  223.  
  224. - setScaleToFit:(BOOL)flag { scaleToFit = flag; return self; }
  225. - (BOOL)scaleToFit { return scaleToFit; }
  226. - setImageUnder:(BOOL)flag { imageUnder = flag; return self; }
  227. - (BOOL)imageUnder { return imageUnder; }
  228.  
  229. - (int)aspectRatioType { return aspectRatioType; }
  230. - (float)aspectRatio { return aspectRatio; }
  231. - setAspectRatioFromMatrix:sender
  232. {
  233.   NXRect  newRect;
  234.  
  235.  
  236.   [self getFrame:&newRect];
  237.   aspectRatioType = [[sender selectedCell] tag];
  238.   switch (aspectRatioType)
  239.   {  case WW_ASPECT_DONT_CARE:
  240.             break;
  241.      case WW_ASPECT_NTSC:  // 1.33:1
  242.             newRect.size.height = newRect.size.width/1.33;
  243.             break;
  244.      case WW_ASPECT_AMERICAN_WIDESCREEN:  // 1.85:1
  245.             newRect.size.height = newRect.size.width/1.85;
  246.             break;
  247.      case WW_ASPECT_EUROPEAN_WIDESCREEN:  // 1.66:1
  248.             newRect.size.height = newRect.size.width/1.66;
  249.             break;
  250.      case WW_ASPECT_VISTA_VISION:  // 2.21:1
  251.             newRect.size.height = newRect.size.width/2.21;
  252.             break;
  253.      case WW_ASPECT_SQUARE:  // 1:1
  254.             if (newRect.size.width < newRect.size.height)
  255.             {  newRect.size.height = newRect.size.width;
  256.         }
  257.         else
  258.         {  newRect.size.width = newRect.size.height;
  259.         }
  260.             break;
  261.      case WW_ASPECT_CUSTOM:  //aspectX:aspectY
  262.             if (aspectRatio < 1.0)
  263.         {  newRect.size.width = newRect.size.height * aspectRatio;
  264.         }
  265.         else
  266.         {  newRect.size.height = newRect.size.width/aspectRatio;
  267.         }
  268.             break;
  269.      default:
  270.             NXLogError("unknown aspect ratio type: %d", aspectRatioType);
  271.             break;
  272.   }
  273.   [self sizeTo:newRect.size.width :newRect.size.height];
  274.  
  275.   return self;
  276. }
  277. - setAspectRatioType:(int)newAspectRatioType
  278. {
  279.   NXRect  newRect;
  280.  
  281.  
  282.   [self getFrame:&newRect];
  283.   aspectRatioType = newAspectRatioType;
  284.   switch (aspectRatioType)
  285.   {  case WW_ASPECT_DONT_CARE:
  286.             break;
  287.      case WW_ASPECT_NTSC:  // 1.33:1
  288.             newRect.size.height = newRect.size.width/1.33;
  289.             break;
  290.      case WW_ASPECT_AMERICAN_WIDESCREEN:  // 1.85:1
  291.             newRect.size.height = newRect.size.width/1.85;
  292.             break;
  293.      case WW_ASPECT_EUROPEAN_WIDESCREEN:  // 1.66:1
  294.             newRect.size.height = newRect.size.width/1.66;
  295.             break;
  296.      case WW_ASPECT_VISTA_VISION:  // 2.21:1
  297.             newRect.size.height = newRect.size.width/2.21;
  298.             break;
  299.      case WW_ASPECT_SQUARE:  // 1:1
  300.             if (newRect.size.width < newRect.size.height)
  301.             {  newRect.size.height = newRect.size.width;
  302.         }
  303.         else
  304.         {  newRect.size.width = newRect.size.height;
  305.         }
  306.             break;
  307.      case WW_ASPECT_CUSTOM:  //aspectX:aspectY
  308.             if (aspectRatio < 1.0)
  309.         {  newRect.size.width = newRect.size.height * aspectRatio;
  310.         }
  311.         else
  312.         {  newRect.size.height = newRect.size.width/aspectRatio;
  313.         }
  314.             break;
  315.      default:
  316.             NXLogError("unknown aspect ratio type: %d", aspectRatioType);
  317.             break;
  318.   }
  319.   [self sizeTo:newRect.size.width :newRect.size.height];
  320.  
  321.   return self;
  322. }
  323. //
  324. - setAspectRatio:sender
  325. {
  326.   NXRect  newRect;
  327.  
  328.  
  329.   [self getFrame:&newRect];
  330.   aspectRatio = [sender floatValue];
  331.  
  332.   if (aspectRatioType != WW_ASPECT_CUSTOM)
  333.   {  return self;
  334.   }
  335.   if (aspectRatio < 1.0)
  336.   {  newRect.size.width = newRect.size.height * aspectRatio;
  337.   }
  338.   else
  339.   {  newRect.size.height = newRect.size.width/aspectRatio;
  340.   }
  341.   [self sizeTo:newRect.size.width :newRect.size.height];
  342.  
  343.   return self;
  344. }
  345. //
  346. - setHorizontalLayoutFromMatrix:sender  {  horizontalLayoutType = [[sender selectedCell] tag];  return self; }
  347. - (int)horizontalLayoutType { return horizontalLayoutType; }
  348.  
  349. - setVerticalLayoutFromMatrix:sender  {  verticalLayoutType = [[sender selectedCell] tag];  return self; }
  350. - (int)verticalLayoutType { return verticalLayoutType; }
  351.  
  352.  
  353. - (NXColor) backgroundColor     { return backgroundColor; }
  354. - setBackgroundColor:(NXColor)c { return backgroundColor = c, self; }
  355. - (float) alpha            { return alpha; }
  356. - setBackgroundAlpha:(float)n    { return alpha = n, self; }
  357.  
  358. - saveImage:sender
  359. {
  360.   static id savePanel=nil;
  361.   NXStream *ts;
  362.  
  363.  
  364.   if (!savePanel) 
  365.   {  savePanel=[SavePanel new];
  366.   }
  367.  
  368.   [savePanel setRequiredFileType:"tiff"];
  369.   if([savePanel runModal])
  370.   {  ts = NXOpenMemory(NULL, 0, NX_WRITEONLY);
  371.      [image writeTIFF:ts allRepresentations:NO usingCompression:NX_TIFF_COMPRESSION_LZW andFactor:1.0];
  372.      NXSaveToFile(ts, [savePanel filename]);
  373.      NXCloseMemory(ts,NX_FREEBUFFER);
  374.   }
  375.  
  376.   return self;
  377. }
  378.  
  379. - setImageFile:(const char *)filename 
  380. {
  381.     // It's actually a bad idea to free this image, because it might be shared...
  382.     if (filename && *filename)
  383.     { image = [NXImage findImageNamed:filename];
  384.       if (!image) 
  385.       {  image = [[NXImage alloc] init];
  386.          [image setDataRetained:YES];
  387.          if (![image loadFromFile:filename])
  388.          {  NXLogError("unable to load image from file <%s>\n", filename);
  389.             return nil; 
  390.       }
  391.       }
  392.     }
  393.     clearTheView = YES;
  394.     [self display];
  395.     clearTheView = NO;
  396.     [window display];
  397.     return self;
  398. }
  399.  
  400. - setImage:i  
  401. {  image = i; 
  402.    clearTheView = YES;
  403.    [self display];
  404.    clearTheView = NO;
  405.    [window display];
  406.    return self; 
  407. }
  408. - image { return image; }
  409.  
  410. - (const char *)getInspectorClassName { return "WWSimpleImageViewIBInspector"; }
  411.  
  412. - revertControlPanel:sender 
  413.    [theColor setColor:[self backgroundColor]];
  414.    [alphaSlider setFloatValue:[self alpha]];
  415.    [horizontalLayoutMatrix selectCellWithTag:[self horizontalLayoutType]];
  416.    [verticalLayoutMatrix selectCellWithTag:[self verticalLayoutType]];
  417.    [borderTypeMatrix selectCellWithTag:[self borderType]];
  418.    clearTheView = YES; [self display];
  419.    clearTheView = NO;  [window display]; NXPing();
  420.  
  421.    return self;
  422. }
  423.  
  424. - loadControlPanel
  425. {
  426.    char buf[MAXPATHLEN + 1];
  427.    id bundle;
  428.  
  429.    
  430.    // we want to support two different things here.  
  431.    // 1st scenario: lots of MovieViews, screen space is expensive, we want to have these control panels 
  432.     
  433.    if (!controlPanel)
  434.    {  bundle = [NXBundle bundleForClass:[self class]];
  435.       [bundle getPath:buf forResource:"WWSimpleImageViewControlPanel" ofType:"nib"];
  436.       [NXApp loadNibFile:buf owner:self withNames:NO fromZone:[self zone]];
  437.       if (!controlPanel)
  438.       {  NXLogError("problem loading WWSimpleMovieViewControlPanel\n");
  439.          return nil;
  440.       }
  441.       [controlPanel setDelegate:self];
  442.    }
  443.    [self revertControlPanel:nil];
  444.    [controlPanel makeKeyAndOrderFront:self];
  445.    return self;
  446. }
  447.  
  448.  
  449. - mouseDown:(NXEvent *)theEvent
  450. {
  451.   if (theEvent->flags & NX_COMMANDMASK)  // show the control panel
  452.   {  [self loadControlPanel];
  453.      return self;
  454.   }
  455.   return self;
  456. }
  457.  
  458.  
  459. #define typeVectorVersion1 "@f"
  460. #define typeValuesVersion1 &image, &alpha
  461.  
  462. #define typeVectorVersion2 "@fif"
  463. #define typeValuesVersion2 &image, &alpha, &aspectRatioType, &aspectRatio
  464.  
  465. #define typeVectorVersion3 "@fifcc"
  466. #define typeValuesVersion3 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit
  467.  
  468. #define typeVectorVersion4 "@fifcci"
  469. #define typeValuesVersion4 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType
  470.  
  471. #define typeVectorVersion5 "@fifccii"
  472. #define typeValuesVersion5 &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType
  473.  
  474. #define typeVector "@fifcciii"
  475. #define typeValues &image, &alpha, &aspectRatioType, &aspectRatio, &imageUnder, &scaleToFit, &borderType, &horizontalLayoutType, &verticalLayoutType
  476.  
  477. - read:(NXTypedStream*)stream 
  478. {
  479.     int version;
  480.     [super read:stream];
  481.  
  482.  
  483.     version = NXTypedStreamClassVersion(stream, "WWSimpleImageView");
  484.     if (version == 0) NXReadTypes(stream, "i", &version), version=1;
  485.     if (version == 1)
  486.     {  NXReadTypes(stream, typeVectorVersion1, typeValuesVersion1);
  487.        backgroundColor = NXReadColor(stream);
  488.        aspectRatioType = WW_ASPECT_SQUARE;
  489.        aspectRatio = 1.0;
  490.        imageUnder = NO;
  491.        scaleToFit = NO;
  492.        borderType = 0;
  493.        horizontalLayoutType = NX_LEFTALIGNED;
  494.        verticalLayoutType = WW_BOTTOMALIGNED;
  495.     } 
  496.     if (version == 2)
  497.     {  NXReadTypes(stream, typeVectorVersion2, typeValuesVersion2);
  498.        backgroundColor = NXReadColor(stream);
  499.        imageUnder = NO;
  500.        scaleToFit = NO;
  501.        borderType = 0;
  502.        horizontalLayoutType = NX_LEFTALIGNED;
  503.        verticalLayoutType = WW_BOTTOMALIGNED;
  504.     }
  505.     if (version == 3)
  506.     {  NXReadTypes(stream, typeVectorVersion3, typeValuesVersion3);
  507.        backgroundColor = NXReadColor(stream);
  508.        borderType = 0;
  509.        horizontalLayoutType = NX_LEFTALIGNED;
  510.        verticalLayoutType = WW_BOTTOMALIGNED;
  511.     } 
  512.     if (version == 4)
  513.     {  NXReadTypes(stream, typeVectorVersion4, typeValuesVersion4);
  514.        backgroundColor = NXReadColor(stream);
  515.        horizontalLayoutType = NX_LEFTALIGNED;
  516.        verticalLayoutType = WW_BOTTOMALIGNED;
  517.     } 
  518.     if (version == 5)
  519.     {  NXReadTypes(stream, typeVectorVersion5, typeValuesVersion5);
  520.        backgroundColor = NXReadColor(stream);
  521.        verticalLayoutType = WW_BOTTOMALIGNED;
  522.     } 
  523.     if (version == 6)
  524.     {  NXReadTypes(stream, typeVector, typeValues);
  525.        backgroundColor = NXReadColor(stream);
  526.     } 
  527.     return self;
  528. }
  529.  
  530.  
  531. - write:(NXTypedStream *)stream 
  532. {
  533.     [super write:stream];
  534.     NXWriteTypes(stream, typeVector, typeValues);
  535.     NXWriteColor(stream, backgroundColor);
  536.  
  537.     return self;
  538. }
  539.  
  540.     
  541.  
  542. @end
  543.